

function Enlarge(select) {
  // 范围元素
  this.ele = document.querySelector(select)
  // .show 的 div 盒子, 结构: div > img
  this.show = this.ele.querySelector('.show')
  // .mask 的 div 盒子(遮罩层), 结构: .show > .mask
  this.mask = this.ele.querySelector('.mask')
  // .enlarge 的 div 盒子, 背景图片
  this.enlarge = this.ele.querySelector('.enlarge')
  // show 盒子的尺寸 如何获取
  // 元素.offsetWidth 和 offsetHeight, 获取到的是元素 内容 + padding + border 的尺寸
  this.show_width = this.show.offsetWidth
  this.show_height = this.show.offsetHeight

  
  this.mask_width = parseInt(window.getComputedStyle(this.mask).width)
  this.mask_height = parseInt(window.getComputedStyle(this.mask).height)
  // 注意: enlarge 盒子默认是隐藏的
  // 获取元素非行内样式
  // 语法: widnow.getComputedStyle(要获取样式的元素).样式名
  this.enlarge_width = parseInt(window.getComputedStyle(this.enlarge).width)
  this.enlarge_height = parseInt(window.getComputedStyle(this.enlarge).height)

  // 背景图的尺寸 如何获取
  // 非行内样式
  this.bg_width = parseInt(window.getComputedStyle(this.enlarge).backgroundSize.split(' ')[0])
  console.log(this.bg_width)
  this.bg_height = parseInt(window.getComputedStyle(this.enlarge).backgroundSize.split(' ')[1])

  // 调用启动器
  this.init()
}

// 书写方法
// 0. 启动器
Enlarge.prototype.init = function () {
  // 去调用所有的方法
  this.setScale()
  this.overOut()
  this.move()
}

// 1. 调整比例
/*
  1. 计算出 mask 盒子的宽度
    mask 盒子的尺寸      enlarge 盒子的尺寸
    --------------  =  -----------------
    show 盒子的尺寸      enlarge 盒子的背景
    mask 盒子的尺寸 = enlarge 盒子的尺寸 * show 盒子的尺寸 / enlarge 盒子的背景
  2. 给 this.mask 盒子设置 width 和 height
    + 设置元素的行内样式
*/
Enlarge.prototype.setScale = function () {

  // 1. 计算出 mask 的 尺寸
  // this.mask_width = this.enlarge_width * this.show_width / this.bg_width
  // this.mask_height = this.enlarge_height * this.show_height / this.bg_height
  console.log(this)
  // 2. 给 this.mask 盒子赋值
  this.mask.style.width = this.mask_width + 'px'
  this.mask.style.height = this.mask_height + 'px'
}

// 2. 移入移出
Enlarge.prototype.overOut = function () {
  // 绑定移入事件
  this.show.addEventListener('mouseenter', () => {
    this.mask.style.display = 'block'
    this.enlarge.style.display = 'block'
  })
  // 绑定移出事件
  this.show.addEventListener('mouseleave', () => {
    this.mask.style.display = 'none'
    this.enlarge.style.display = 'none'
  })
}

// 4. 移动联动
/*
  1. 给元素绑定事件
    => 给谁 绑定什么 事件
    => 事件类型: mousemove
    => 事件源: this.show
    => 因为只要光标在 show 盒子范围内移动的时候, mask 盒子都要移动
  2. 获取坐标点
    => 方案1:
      -> 获取相对于页面左上角的坐标点
      -> 注意: 不要用相对于窗口的, 要用相对于页面的
      -> 减去 ele 盒子相对于页面左边和上边的偏移量
      -> 在减去 ele 盒子的 1px 的边框
    => 方案2:
      -> 获取相对于元素左上角的坐标位置
      -> 因为 mask 刚好是相对于 show 盒子进行的定位
      -> 如果我能拿到相对于 show 盒子左上角的位置
      -> 相对于 事件目标 的左上角
      -> 当你光标移入到 mask 盒子里面以后, 坐标位置就变了
      -> 只要 mask 盒子不作为事件目标
      -> 可以给 mask 盒子添加一个样式 pointer-events: none;
  3. 进行边界值判断
    => 左: x <= 0 让 x = 0
    => 上: y <= 0 让 y = 0
    => 右: x >= show_width - mask_width
    => 下: y >= show_height - mask_height

  4. 把 x 和 y 赋值给 mask 盒子
    => 分别赋值给 left 和 top

  5. 让背景图联动
    => 我们只要计算出尺寸, 让他以负数的形式赋值
    => 比例: 背景图的尺寸 / 图片盒子的尺寸(show盒子的尺寸) * mask 盒子移动的距离
*/
Enlarge.prototype.move = function () {

  // 1. 给 this.show 绑定鼠标移动事件
  this.show.addEventListener('mousemove', e => {
    // 处理事件对象兼容
    e = e || window.event
    // 2. 获取光标的坐标点
    // 方案1:
    // let x = e.pageX - this.ele.offsetLeft - this.ele.clientLeft - this.mask_width / 2
    // let y = e.pageY - this.ele.offsetTop - this.ele.clientTop - this.mask_width / 2
    // 方案2:
    let x = e.offsetX - this.mask_width / 2
    let y = e.offsetY - this.mask_height / 2

    // 3. 边界值判断
    if (x <= 0) x = 0
    if (y <= 0) y = 0
    if (x >= this.show_width - this.mask_width) x = this.show_width - this.mask_width
    if (y >= this.show_height - this.mask_height) y = this.show_height - this.mask_height

    // 4. 给 mask 的 left 和 top 进行赋值
    this.mask.style.left = x + 'px'
    this.mask.style.top = y + 'px'

    // 5. 让背景图联动
    // 计算出数字
    // 比例: 背景图的尺寸 / 图片盒子的尺寸(show盒子的尺寸) * mask 盒子移动的距离
    const bg_x = this.bg_width / this.show_width * x
    const bg_y = this.bg_height / this.show_height * y

    // 给 enlarge 盒子的 backgroundPosition 设置值
    this.enlarge.style.backgroundPosition = `-${ bg_x }px -${ bg_y }px`
  })
}
